package com.example.sandbox.handler;

import com.alibaba.fastjson.JSONObject;
import com.example.sandbox.helper.BizException;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.Objects;

/**
 * @desc: 统一错误处理
 * @author: liuxinxin
 * @date: 2024/04/19
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 处理业务异常
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = HttpMessageNotReadableException.class)
    public ApiResponse handlerHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        log.error("Biz exception occurred", e); // 记录详细异常信息
        // 可以加入针对BizException的特定通知逻辑 here
        // 返回具体的错误信息
        return ApiResponse.buildFailure("500", e.getMessage());
    }

    @ResponseBody
    @ExceptionHandler(value = IllegalArgumentException.class)
    public ApiResponse handlerIllegalArgumentException(IllegalArgumentException e) {
        log.error("Biz exception occurred", e); // 记录详细异常信息
        // 可以加入针对BizException的特定通知逻辑 here
        // 返回具体的错误信息
        return ApiResponse.buildFailure("500", e.getMessage());
    }

    /**
     * 处理业务异常
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ApiResponse handlerMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        // 返回具体的错误信息
        BindingResult bindingResult = e.getBindingResult();

        JSONObject result = new JSONObject();
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            String fieldName = fieldError.getField();
            String errorMessage = fieldError.getDefaultMessage();
            // 在这里可以对字段名和错误信息进行处理
            result.put(fieldName, errorMessage);
        }
        return ApiResponse.buildFailure("415", JSONObject.toJSONString(result));
    }

    /**
     * 处理业务异常
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = BizException.class)
    public ApiResponse handlerBizException(BizException e) {
        LOGGER.error("Biz exception occurred", e); // 记录详细异常信息
        // 可以加入针对BizException的特定通知逻辑 here
        // 返回具体的错误信息
        if (Objects.isNull(e.getCode())) {
            return ApiResponse.buildFailure("500", e.getMessage());
        } else {
            return ApiResponse.buildFailure(e.getStrCode(), e.getMessage());
        }
    }

    /**
     * 拦截未知的运行时异常
     */
    @ExceptionHandler(RuntimeException.class)
    @ResponseBody
    public ApiResponse runtimeException(RuntimeException e) {
        LOGGER.error("[系统异常]", e);
        return ApiResponse.buildFailure("500", "系统异常");
    }

    /**
     * 拦截未知的运行时异常
     */
    @ExceptionHandler(Throwable.class)
    @ResponseBody
    public ApiResponse runtimeException(Throwable e) {
        LOGGER.error("[系统异常]", e);
        return ApiResponse.buildFailure("500", "系统异常");
    }

}
